package com.shanks.framework.mq.monitor;

import jakarta.annotation.Resource;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 消息监控初始化
 */
@Component
public class MessageMonitorInitializer implements ApplicationListener<ContextRefreshedEvent> {
    private volatile boolean isInitialized = false;

    @Resource(name = "mqTaskScheduleTakExcutor")
    private ScheduledExecutorService scheduledExecutorService;

    @Resource
    private MessagePendingMonitor messagePendingMonitor;

    @Resource
    private MessageSentMonitor messageSentMonitor;

    @Resource
    private MessageSendingMonitor messageSendingMonitor;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (!isInitialized) {
            synchronized (this) {
                if (!isInitialized) { // 双重检查锁定
                    isInitialized = true;
                    scheduleInitialization();
                }
            }
        }
    }

    private void scheduleInitialization() {
        scheduledExecutorService.schedule(this::initializeThreads, 5, TimeUnit.SECONDS);
    }

    /**
     * 初始化线程
     */
    private void initializeThreads() {
        // 待发送消息线程
        createAndStartThread("PendingMessageMonitor", this::monitorPendingMessages);
        // 已发送未确认ack线程
        createAndStartThread("SentMessageMonitor", this::monitorSentMessages);
        // 发送中线程
        // 已发送未确认ack线程
        createAndStartThread("SendingMessageMonitor", this::monitorSendingMessages);
    }

    /**
     * 监控待发送消息
     */
    private void monitorPendingMessages() {
        messagePendingMonitor.monitorPendingMessages();
    }

    /**
     * 监控已发送未确认ack消息
     */
    private void monitorSentMessages() {
        messageSentMonitor.monitorSentMessages();
    }

    private void monitorSendingMessages() {
        messageSendingMonitor.monitorSendingMessages();
    }

    private void createAndStartThread(String threadName, Runnable runnable) {
        Thread thread = new Thread(runnable);
        thread.setName(threadName);
        thread.setDaemon(true);
        thread.start();
    }
}
